<template>
  <div class="rollCall-container">
    <!-- 导入区域 -->
    <!-- <div class="import-container">
      <el-upload
        class="upload-demo"
        action=""
        :on-change="handleFileChange"
        :before-upload="beforeUpload"
        :auto-upload="false"
        accept=".txt"
        :show-file-list="false"
      >
        <el-button type="primary" :disabled="isRolling">
          <i class="el-icon-upload2"></i> 导入学生名单
        </el-button>
        <div class="upload-hint">支持格式：.txt，每行一条数据，格式为"学号 姓名"</div>
      </el-upload>

      <el-button
        type="danger"
        @click="clearStudentList"
        :disabled="isRolling || data.length === 0"
        style="margin-left: 10px;"
      >
        <i class="el-icon-delete"></i> 清空名单
      </el-button>
    </div> -->

    <!-- 原有标签球区域 -->
    <div
      class="wordCloud__tagBall"
      :style="{width:`${this.width}px`,height:`${this.height}px`}"
    >
      <div
        class="wordCloud__tag"
        v-for="(student, index) of data"
        :key="index"
        :style="{
          color: selectedIndexes.includes(index) ? '#ff4d4f' : color[index % color.length],
          ...contentEle[index].style
        }"
      >
        <i class="el-icon-user-solid" />
        <span>{{ student.name }}</span>
        <span class="student-id">{{ student.id }}</span>
      </div>
    </div>

    <!-- 按钮和人数设置区域 -->
    <div class="wordCloud__home">
      <el-select
        v-model="rollCallCount"
        placeholder="选择点名人数"
        :disabled="isRolling"
        style="width: 160px; margin-right: 10px;"
      >
        <el-option
          v-for="count in [1, 2, 3, 4, 5]"
          :key="count"
          :label="`${count}人`"
          :value="count"
        />
      </el-select>
      <el-button
        type="success"
        @click="startRollCall"
        :disabled="isRolling || data.length === 0"
      >开始点名</el-button>
      <el-button
        type="warning"
        @click="stopRollCall"
        :disabled="!isRolling"
      >停止点名</el-button>
      <el-button
        type="primary"
        @click="handleRotate('-1')"
        :disabled="isRolling"
      >横向顺时针</el-button>
      <el-button
        type="primary"
        @click="handleRotate('1')"
        :disabled="isRolling"
      >横向逆时针</el-button>
      <el-button
        type="primary"
        @click="handleRotate('-2')"
        :disabled="isRolling"
      >纵向顺时针</el-button>
      <el-button
        type="primary"
        @click="handleRotate('2')"
        :disabled="isRolling"
      >纵向逆时针</el-button>
    </div>

    <!-- 结果展示区域 -->
    <div v-if="selectedStudents.length > 0" class="result-display">
      <h3>被点到的同学：</h3>
      <div class="selected-list">
        <div class="selected-item" v-for="student in selectedStudents" :key="student.id">
          {{ student.name }}（{{ student.id }}）
        </div>
      </div>
    </div>

    <!-- 学生列表卡片区域 -->
    <div class="student-list-container">
      <el-card class="student-list-card">
        <div slot="header">
          <h3>学生名单 (共 {{ data.length }} 人)</h3>
        </div>
        <div class="student-grid">
          <div
            v-for="(student, index) of data"
            :key="index"
            class="student-card"
            :class="{ 'selected': selectedIndexes.includes(index) }"
          >
            <el-avatar icon="el-icon-user-solid" :style="{ backgroundColor: color[index % color.length] }" />
            <span class="student-name">{{ student.name }}</span>
            <span class="student-id">{{ student.id }}</span>
          </div>
          <div v-if="data.length === 0" class="empty-hint">
            暂无学生数据，请导入学生名单
          </div>
        </div>
      </el-card>
    </div>
  </div>
</template>


<script>
/* eslint-disable no-mixed-operators */
export default {
  name: 'StudentRollCall',
  data: () => ({
    data: [],
    color: ['#2D4DB6', '#04B67C', '#D1AF07', '#E27914', '#CB4A4D', '#B02690'],
    contentEle: [],
    width: 600,
    height: 500,
    direction: '-1',
    speed: 200,
    isRolling: false,
    selectedIndexes: [], // 存储选中的索引数组
    selectedStudents: [], // 存储选中的学生数组
    rollCallCount: 1, // 点名人数设置
    originalSpeed: 200
  }),
  created() {
    // 初始学生名单（包含学号信息）
    this.data = [
      { id: '2023001', name: '张三' },
      { id: '2023002', name: '李四' },
      { id: '2023003', name: '王五' },
      { id: '2023004', name: '赵六' },
      { id: '2023005', name: '钱七' },
      { id: '2023006', name: '孙八' },
      { id: '2023007', name: '周九' },
      { id: '2023008', name: '吴十' }
    ];
    this.contentEle = this.data.map(() => ({
      x: 0,
      y: 0,
      z: 0,
      style: {}
    }));
    this.originalSpeed = this.speed;
  },
  mounted() {
    this.innit();
  },
  methods: {
    // 处理文件上传
    handleFileChange(file) {
      const reader = new FileReader();
      reader.onload = (e) => {
        try {
          const content = e.target.result;
          const students = this.parseStudentData(content);

          if (students.length > 0) {
            this.data = students;
            this.contentEle = this.data.map(() => ({
              x: 0,
              y: 0,
              z: 0,
              style: {}
            }));
            this.innit(); // 重新初始化标签球
            this.selectedIndexes = [];
            this.selectedStudents = [];

            this.$message({
              message: `成功导入 ${students.length} 名学生`,
              type: 'success'
            });
          }
        } catch (error) {
          this.$message.error(`导入失败: ${error.message}`);
        }
      };
      reader.readAsText(file.raw);
    },

    // 解析学生数据
    parseStudentData(content) {
      const lines = content.split('\n');
      const students = [];
      const idSet = new Set(); // 用于检测重复学号

      if (lines.length === 0) {
        throw new Error('文件内容为空');
      }

      lines.forEach((line, index) => {
        const trimmedLine = line.trim();
        if (!trimmedLine) return; // 跳过空行

        // 按空格分割，支持多个空格分隔
        const parts = trimmedLine.split(/\s+/);

        if (parts.length !== 2) {
          throw new Error(`第 ${index + 1} 行格式错误，正确格式应为"学号 姓名"`);
        }

        const [id, name] = parts;

        if (!id || !name) {
          throw new Error(`第 ${index + 1} 行数据不完整`);
        }

        if (idSet.has(id)) {
          throw new Error(`第 ${index + 1} 行学号重复: ${id}`);
        }

        idSet.add(id);
        students.push({ id, name });
      });

      if (students.length === 0) {
        throw new Error('未找到有效学生数据');
      }

      return students;
    },

    // 上传前检查
    beforeUpload(file) {
      const isTxt = file.type === 'text/plain' || file.name.endsWith('.txt');
      if (!isTxt) {
        this.$message.error('只能上传TXT格式的文件!');
        return false;
      }
      return true;
    },

    // 清空学生列表
    clearStudentList() {
      this.$confirm('确定要清空所有学生数据吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.data = [];
        this.contentEle = [];
        this.selectedIndexes = [];
        this.selectedStudents = [];
        this.innit();
        this.$message({
          type: 'success',
          message: '已清空学生列表'
        });
      }).catch(() => {
        // 取消操作
      });
    },

    innit() {
      const RADIUSX = (this.width - 50) / 2;
      const RADIUSY = (this.height - 50) / 2;
      this.contentEle = [];
      for (let i = 0; i < this.data.length; i += 1) {
        const k = -1 + (2 * (i + 1) - 1) / this.data.length;
        const a = Math.acos(k);
        const b = a * Math.sqrt(this.data.length * Math.PI);
        const x = RADIUSX * Math.sin(a) * Math.cos(b);
        const y = RADIUSY * Math.sin(a) * Math.sin(b);
        const z = RADIUSX * Math.cos(a);
        const singleEle = {
          x,
          y,
          z,
          style: {}
        };
        this.contentEle.push(singleEle);
      }
      this.animate();
    },
    animate() {
      if (this.isRolling) {
        // 点名时加速旋转
        this.rotateX(true);
        this.rotateY(true);
      } else {
        this.rotateX();
        this.rotateY();
      }
      this.move();
      window.requestAnimationFrame(this.animate);
    },
    rotateX(isFast = false) {
      const speedFactor = isFast ? 5 : 1;
      const angleX = ['-1', '1'].includes(this.direction)
        ? Math.PI / Infinity
        : Math.PI / ((Number(this.direction) / 2) * Number(this.speed) / speedFactor);
      const cos = Math.cos(angleX);
      const sin = Math.sin(angleX);

      this.contentEle = this.contentEle.map((t) => {
        const y1 = t.y * cos - t.z * sin;
        const z1 = t.z * cos + t.y * sin;
        return {
          ...t,
          y: y1,
          z: z1
        };
      });
    },
    rotateY(isFast = false) {
      const speedFactor = isFast ? 5 : 1;
      const angleY = ['-2', '2'].includes(this.direction)
        ? Math.PI / Infinity
        : Math.PI / (Number(this.direction) * Number(this.speed) / speedFactor);
      const cos = Math.cos(angleY);
      const sin = Math.sin(angleY);
      this.contentEle = this.contentEle.map((t) => {
        const x1 = t.x * cos - t.z * sin;
        const z1 = t.z * cos + t.x * sin;
        return {
          ...t,
          x: x1,
          z: z1
        };
      });
    },
    move() {
      const CX = this.width / 2;
      const CY = this.height / 2;
      this.contentEle = this.contentEle.map((singleEle, index) => {
        const { x, y, z } = singleEle;
        const fallLength = 500;
        const RADIUS = (this.width - 50) / 2;
        const scale = fallLength / (fallLength - z);
        const alpha = (z + RADIUS) / (2 * RADIUS);
        const left = `${x + CX - 15}px`;
        const top = `${y + CY - 15}px`;
        const transform = `translate(${left}, ${top}) scale(${scale})`;
        // 为选中的学生添加特殊样式
        const style = {
          ...singleEle.style,
          opacity: alpha + 0.5,
          zIndex: parseInt(scale * 100, 10),
          transform,
          transition: this.isRolling ? 'none' : 'all 0.3s ease',
          fontSize: this.selectedIndexes.includes(index) ? '24px' : '15px',
          fontWeight: this.selectedIndexes.includes(index) ? 'bold' : 'normal'
        };
        return {
          x,
          y,
          z,
          style
        };
      });
    },
    handleRotate(value) {
      this.direction = value;
    },
    startRollCall() {
      this.isRolling = true;
      this.selectedStudents = [];
      this.selectedIndexes = [];
      // 重置所有样式
      this.contentEle = this.contentEle.map(ele => ({
        ...ele,
        style: {
          ...ele.style,
          fontSize: '15px',
          fontWeight: 'normal'
        }
      }));
    },
    stopRollCall() {
      this.isRolling = false;
      // 随机选择指定数量的学生（不重复）
      const count = Math.min(this.rollCallCount, this.data.length);
      const selected = new Set();

      while (selected.size < count) {
        const randomIndex = Math.floor(Math.random() * this.data.length);
        selected.add(randomIndex);
      }

      this.selectedIndexes = Array.from(selected);
      this.selectedStudents = this.selectedIndexes.map(index => this.data[index]);
    }
  }
};
</script>


<style lang="less" scoped>
.rollCall-container {
  text-align: center;
  padding: 20px;
  margin: auto;
  max-width: 1200px;
}

// 导入区域样式
.import-container {
  margin-bottom: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
}

.upload-hint {
  margin-left: 10px;
  color: #666;
  font-size: 12px;
  line-height: 32px;
}

.wordCloud__tagBall {
  margin: 50px auto;
  position: relative;
}

.wordCloud__tag {
  display: flex;
  flex-direction: column;
  align-items: center;
  position: absolute;
  left: 0px;
  top: 0px;
  color: green;
  text-decoration: none;
  font-size: 15px;
  font-family: '微软雅黑';
  font-weight: bold;
  transition: all 0.3s ease;

  &:hover {
    color: #ff4d4f;
    cursor: pointer;
  }

  .student-id {
    font-size: 12px;
    opacity: 0.8;
    margin-top: 3px;
  }
}

.wordCloud__home {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-bottom: 30px;
  flex-wrap: wrap;
  padding: 0 20px;
  align-items: center;
}

.result-display {
  margin-top: 20px;
  padding: 20px;
  border-radius: 8px;
  background-color: #f5f5f5;
  display: inline-block;
}

.selected-list {
  margin-top: 10px;
}

.selected-item {
  font-size: 22px;
  color: #ff4d4f;
  font-weight: bold;
  margin: 5px 0;
}

// 学生列表样式
.student-list-container {
  margin-top: 40px;
  padding: 0 20px;
}

.student-list-card {
  width: 100%;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.student-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 15px;
  padding: 10px;
  min-height: 100px;
}

.empty-hint {
  grid-column: 1 / -1;
  text-align: center;
  padding: 30px;
  color: #999;
  font-size: 14px;
}

.student-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 15px;
  border-radius: 6px;
  transition: all 0.3s ease;
  background-color: #f9f9f9;

  &:hover {
    background-color: #f0f7ff;
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  }

  &.selected {
    background-color: #fff1f0;
    border: 2px solid #ff4d4f;
  }

  .student-id {
    font-size: 12px;
    color: #666;
    margin-top: 5px;
  }
}

.student-name {
  margin-top: 10px;
  font-size: 14px;
  font-weight: 500;
}
</style>
